home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / wb / flynn / source / flynnapp.c < prev    next >
C/C++ Source or Header  |  1999-06-15  |  12KB  |  631 lines

  1.  
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <time.h>
  7.  
  8. #include <intuition/intuition.h>
  9. #include <dos/dos.h>
  10. #include <libraries/screennotify.h>
  11. #include <workbench/workbench.h>
  12. #include <workbench/startup.h>
  13.  
  14.  
  15. #include <proto/intuition.h>
  16. #include <proto/dos.h>
  17. #include <proto/exec.h>
  18. #include <proto/guigfx.h>
  19. #include <proto/graphics.h>
  20. #include <proto/screennotify.h>
  21. #include <proto/icon.h>
  22.  
  23. #include "flynnapp.h"
  24. #include "global.h"
  25. #include "defs.h"
  26. #include "subtask.h"
  27. #include "flynnpic.h"
  28. #include "tools.h"
  29.  
  30.  
  31.  
  32. void inputloop (struct FlynnApp *flynnapp);
  33. struct FlynnApp *CreateFlynnApp(void);
  34. void DeleteFlynnApp(struct FlynnApp *app);
  35. void ReadConfig(struct FlynnApp *app);
  36. void WriteConfig(struct FlynnApp *app);
  37.  
  38.  
  39.  
  40.  
  41. int flynn_idle[] = {0,0,5,0,0,10,0,0,0,0,5,5,0,0,0,5,0,0,0,10,0,0,10,10,0,-1};
  42. int flynn_hate[] = {15, -1};
  43. int flynn_evil[] = {20, -1};
  44. int flynn_dead[] = {25, -1};
  45. int flynn_god[] = {26, -1};
  46. int *flynn_anim[] = {flynn_idle, flynn_evil, flynn_hate, flynn_dead, flynn_god, NULL};
  47.  
  48.  
  49.  
  50.  
  51. LONG __saveds idlefunc(APTR subtask, BYTE abortsignal)
  52. {
  53.     struct idledata *data;
  54.     ULONG abortsignals = 1 << abortsignal, signals;
  55.     struct Task *mytask = FindTask(NULL);
  56.     
  57.     data = ObtainData(subtask);
  58.  
  59.     data->count = 0;
  60.     
  61.     do
  62.     {
  63.         LONG newpri = ((drand48() * 2.0 - 1.0) * (drand48() * 2.0 - 1.0)) * 7.0;
  64.         SetTaskPri(mytask, newpri); 
  65.         Delay(4);
  66.         data->count++;
  67.         signals = SetSignal(0, abortsignals);
  68.     
  69.     } while (!(signals & abortsignals));
  70.     
  71.     
  72.     ReleaseData(subtask);
  73.  
  74.     return 0;
  75. }
  76.  
  77.  
  78.  
  79.  
  80.  
  81. static int evilcount = 0;
  82.  
  83. static int updateflynn(struct FlynnApp *app)
  84. {
  85.     int index;    
  86.     static int lastcount = 0;
  87.     float oldhealth, newhealth;
  88.     static int hatecount = 0;
  89.  
  90.     oldhealth = app->flynnhealth;
  91.  
  92.     app->flynnhealth -= 0.20;
  93.     app->flynnhealth += (app->idledata.count - lastcount) / 21.0;
  94.  
  95.     if (app->flynnhealth < 0.01) app->flynnhealth = 0.01;
  96.     if (app->flynnhealth > 1.0) app->flynnhealth = 1.0;
  97.  
  98.     newhealth = app->flynnhealth;
  99.     lastcount = app->idledata.count;
  100.  
  101.  
  102.     if (newhealth - oldhealth < -0.20)
  103.     {
  104.         app->flynnanimptr = NULL;
  105.         app->flynnmode = FLYNN_HATE;
  106.         hatecount = 6;
  107.     }
  108.     
  109.     if (app->flynnmode == FLYNN_HATE)
  110.     {
  111.         if (--hatecount <= 0)
  112.         {
  113.             app->flynnanimptr = NULL;
  114.             app->flynnmode = FLYNN_IDLE;
  115.         }
  116.     }
  117.  
  118.     if (app->flynnmode == FLYNN_EVIL)
  119.     {
  120.         if (--evilcount <= 0)
  121.         {
  122.             app->flynnanimptr = NULL;
  123.             app->flynnmode = FLYNN_IDLE;
  124.         }
  125.     }
  126.     
  127.  
  128.  
  129.  
  130.     if (app->flynnanimptr)
  131.     {
  132.         app->flynnanimptr++;
  133.         if (*app->flynnanimptr == -1)
  134.         {
  135.             app->flynnanimptr = NULL;    
  136.         }
  137.     }
  138.  
  139.     if (app->flynnanimptr == NULL)
  140.     {
  141.         app->flynnanimptr = flynn_anim[app->flynnmode];
  142.     }
  143.  
  144.  
  145.  
  146.     index = *app->flynnanimptr + (1.0 - app->flynnhealth) * 5;
  147.  
  148.  
  149.     return index;
  150. }
  151.  
  152.  
  153.  
  154. void main(void)
  155. {
  156.  
  157.     if (InitGlobal())
  158.     {
  159.         struct FlynnApp *app;
  160.     
  161.         if (app = CreateFlynnApp())
  162.         {
  163.             int oldpri = SetTaskPri(FindTask(NULL), 2);
  164.             srand(time(NULL));
  165.             inputloop(app);
  166.             SetTaskPri(FindTask(NULL), oldpri);
  167.  
  168.             DeleteFlynnApp(app);
  169.         }
  170.  
  171.         CloseGlobal();
  172.     }
  173. }
  174.  
  175.  
  176.  
  177.  
  178. void inputloop (struct FlynnApp *app)
  179. {
  180.     BOOL finish = FALSE;
  181.     ULONG signals;
  182.     ULONG idcmpsignals;
  183.     ULONG scrnotifysignals = 0;
  184.     struct IntuiMessage *imsg;
  185.     struct IntuiMessage myimsg;
  186.     int last_index = -1, new_index;
  187.     BOOL refresh = TRUE;
  188.     int writeconfig = 0;
  189.     APTR dh = NULL;
  190.  
  191.     
  192.     if (ScreenNotifyBase && app->scrmsgport && app->scrnotifyhandle)
  193.     {
  194.         scrnotifysignals = (1 << app->scrmsgport->mp_SigBit);
  195.     }
  196.  
  197.  
  198.     do
  199.     {
  200.         new_index = updateflynn(app);
  201.  
  202.         if (!dh && app->window)
  203.         {
  204.  
  205.             ClearWindow(app->window);
  206.             dh = ObtainDrawHandle(app->psm, app->window->window->RPort,
  207.                 app->window->screen->ViewPort.ColorMap, 
  208.                 GGFX_DitherMode, DITHERMODE_NONE,
  209.                 GGFX_AutoDither, FALSE, TAG_DONE);
  210.         }
  211.         
  212.         if (dh && app->window)
  213.         {
  214.             if (new_index != last_index || refresh)
  215.             {
  216.                 DrawPicture(dh, app->flynnpicture,
  217.                     app->window->innerleft + BORDERX,
  218.                     app->window->innertop + BORDERY,
  219.                     GGFX_SourceWidth, FLYNNWIDTH, GGFX_SourceX, 0,
  220.                     GGFX_SourceHeight, FLYNNHEIGHT, 
  221.                     GGFX_SourceY, new_index * FLYNNHEIGHT,
  222.                         GGFX_DestWidth, app->window->innerwidth - BORDERX*2,
  223.                     GGFX_DestHeight, app->window->innerheight - BORDERY*2,
  224.                     TAG_DONE);
  225.                 last_index = new_index;
  226.             }
  227.         }
  228.     
  229.  
  230.         if (refresh)
  231.         {
  232.             refresh = FALSE;
  233.         }
  234.         else
  235.         {
  236.             Delay( (ULONG)((drand48() - 0.5) * 7.0 + 25.0));
  237.         }
  238.  
  239.         idcmpsignals = app->window ? app->window->idcmpSignal : 0;
  240.  
  241.         signals = SetSignal(0, SIGBREAKF_CTRL_C | idcmpsignals | scrnotifysignals);
  242.  
  243.     
  244.  
  245.         if ((signals & idcmpsignals) && app->window)
  246.         {
  247.             while (imsg = (struct IntuiMessage *) GetMsg(app->window->window->UserPort))
  248.             {
  249.                 memcpy(&myimsg, imsg, sizeof(struct IntuiMessage));
  250.                 ReplyMsg((struct Message *) imsg);
  251.  
  252.                 switch (myimsg.Class)
  253.                 {
  254.                     case ACTIVEWINDOW:
  255.                     case INACTIVEWINDOW:
  256.                         writeconfig = 10;
  257.                         break;
  258.                         
  259.                     case MOUSEBUTTONS:
  260.                     //        printf("icode %ld\n", myimsg.Code);
  261.                         if (myimsg.Code == 233)
  262.                         {
  263.                             app->flynnanimptr = NULL;
  264.                             app->flynnmode = FLYNN_EVIL;
  265.                             evilcount = 3;
  266.                         }
  267.                     //    else
  268.                     //    {
  269.                     //        app->flynnhealth -= 0.2;
  270.                     //    }
  271.                         break;
  272.  
  273.                     case NEWSIZE:
  274.                         ClearWindow(app->window);
  275.                         UpdateWindowParameters(app->window);
  276.                         app->window->sizegadget.LeftEdge = app->window->window->Width-SIZESIZE;
  277.                         app->window->sizegadget.TopEdge = app->window->window->Height-SIZESIZE;
  278.                         app->window->draggadget.Width = app->window->window->Width;
  279.                         app->window->draggadget.Height = app->window->window->Height;
  280.                         refresh = TRUE;
  281.                         writeconfig = 10;
  282.                         break;
  283.  
  284.                     case VANILLAKEY:
  285.                         switch (myimsg.Code)
  286.                         {
  287.                             case 27:
  288.                                 finish = TRUE;
  289.                                 break;
  290.                         }
  291.                 }
  292.  
  293.             }
  294.         }
  295.  
  296.         if (signals & scrnotifysignals)
  297.         {
  298.             struct ScreenNotifyMessage *snm;
  299.  
  300.             while (snm = (struct ScreenNotifyMessage *) GetMsg(app->scrmsgport))
  301.             {
  302.                 if (snm->snm_Type == SCREENNOTIFY_TYPE_WORKBENCH)
  303.                 {
  304.                     if (snm->snm_Value == FALSE)
  305.                     {
  306.                         if (app->window)
  307.                         {
  308.                             app->winx = app->window->window->LeftEdge;
  309.                             app->winy = app->window->window->TopEdge;
  310.                             app->winwidth = app->window->window->Width;
  311.                             app->winheight = app->window->window->Height;
  312.                             
  313.                             ReleaseDrawHandle(dh);
  314.                             dh = NULL;
  315.                             DeleteMVWindow(app->window);
  316.                             app->window = NULL;
  317.                         }
  318.                     }
  319.                     else
  320.                     {
  321.                         if (!app->window)
  322.                         {
  323.                             if (!(app->window = CreateMVWindow(app->winx, app->winy, app->winwidth, app->winheight)))
  324.                             {
  325.                                 finish = TRUE;
  326.                             }
  327.                         }
  328.                     }
  329.                 }
  330.                 ReplyMsg((struct Message *) snm);
  331.             }
  332.         }
  333.  
  334.         if (writeconfig)
  335.         {
  336.             if (--writeconfig == 0)
  337.             {
  338.                 WriteConfig(app);
  339.             }
  340.         }
  341.  
  342.         if (signals & SIGBREAKF_CTRL_C)
  343.         {
  344.             finish = TRUE;
  345.         }
  346.         
  347.     } while (!finish);
  348.  
  349.  
  350.     SetRast(app->window->window->RPort, app->window->backpen);
  351.  
  352.     ReleaseDrawHandle(dh);
  353.  
  354. }
  355.  
  356.  
  357.  
  358.  
  359.  
  360. struct FlynnApp *CreateFlynnApp(void)
  361. {
  362.     struct FlynnApp *app;
  363.     BOOL success = FALSE;
  364.  
  365.     
  366.     if (app = Malloclear(sizeof(struct FlynnApp)))
  367.     {
  368.         app->winx = -1;        
  369.         app->winy = -1;        
  370.         app->winwidth = APPWIDTH;
  371.         app->winheight = APPHEIGHT;
  372.         
  373.         if (_WBenchMsg)
  374.         {
  375.             if (NameFromLock(GetProgramDir(), app->filenamebuffer, MAXNAMELEN))
  376.             {
  377.                 if (AddPart(app->filenamebuffer, _WBenchMsg->sm_ArgList[0].wa_Name, MAXNAMELEN))
  378.                 {
  379.                     app->progname = StrDup(app->filenamebuffer);
  380.                 }
  381.             }
  382.         }
  383.         else
  384.         {
  385.             if (GetProgramName(app->filenamebuffer, MAXNAMELEN))
  386.             {
  387.                 char *s;
  388.                 if (s = StrDup(app->filenamebuffer))
  389.                 {
  390.                     if (NameFromLock(GetProgramDir(), app->filenamebuffer, MAXNAMELEN))
  391.                     {
  392.                         if (AddPart(app->filenamebuffer, s, MAXNAMELEN))
  393.                         {
  394.                             app->progname = StrDup(app->filenamebuffer);
  395.                         }
  396.                     }
  397.                     Free(s);
  398.                 }
  399.             }
  400.         }
  401.  
  402.         ReadConfig(app);
  403.         
  404.         if (app->subtask = SubTask(idlefunc, &app->idledata, 1000, 0, "flynn idletask (%x)", NULL, FALSE))
  405.         {
  406.             app->window = CreateMVWindow(app->winx, app->winy, app->winwidth, app->winheight);
  407.  
  408.         //    app->flynnpicture = LoadPicture("flynn.picture", TAG_DONE);
  409.             
  410.             app->flynnpicture = MakePicture(flynndata, 24, 864, 
  411.                 GGFX_NumColors, 256, GGFX_Palette, flynnpalette, TAG_DONE);
  412.             
  413.             
  414.             app->psm = CreatePenShareMap(TAG_DONE);
  415.             
  416.             app->flynnhealth = 1.0;
  417.             app->flynnmode = FLYNN_IDLE;
  418.             app->flynnanimptr = NULL;
  419.             
  420.             if (app->window && app->flynnpicture && app->psm)
  421.             {
  422.                 if (ScreenNotifyBase)
  423.                 {
  424.                     if (app->scrmsgport = CreateMsgPort())
  425.                     {
  426.                         app->scrnotifyhandle = AddWorkbenchClient(app->scrmsgport, 0);
  427.                     }
  428.                 }
  429.             
  430.                 GetPictureAttrs(app->flynnpicture,
  431.                     PICATTR_Width, &app->flynnwidth,
  432.                     PICATTR_Height, &app->flynnheight,
  433.                     TAG_DONE);
  434.         
  435.                 AddPicture(app->psm, app->flynnpicture, TAG_DONE);
  436.         
  437.         
  438.         
  439.         
  440.                 success = TRUE;        
  441.             }        
  442.  
  443.         }
  444.         
  445.     }
  446.  
  447.  
  448.     if (!success)
  449.     {
  450.         DeleteFlynnApp(app);
  451.         app = NULL;
  452.     }
  453.     
  454.     return app;
  455. }
  456.  
  457.  
  458.  
  459. void DeleteFlynnApp(struct FlynnApp *app)
  460. {
  461.     if (app)
  462.     {
  463.         if (app->window)
  464.         {
  465.             WriteConfig(app);
  466.         }
  467.  
  468.         Free(app->progname);
  469.  
  470.         if (ScreenNotifyBase)
  471.         {
  472.             if (app->scrnotifyhandle)
  473.             {
  474.                 while (!RemWorkbenchClient(app->scrnotifyhandle))
  475.                 {
  476.                     Delay(10);
  477.                 }
  478.             }
  479.             DeleteMsgPort(app->scrmsgport);
  480.         }
  481.     
  482.         if (app->subtask)
  483.         {
  484.             AbortSubTask(app->subtask);
  485.             CloseSubTask(app->subtask);
  486.         }
  487.  
  488.         DeletePenShareMap(app->psm);
  489.         DeletePicture(app->flynnpicture);
  490.         DeleteMVWindow(app->window);
  491.         Free(app);    
  492.     }
  493.  
  494. }
  495.  
  496.  
  497.  
  498.  
  499.  
  500. void ReadConfig(struct FlynnApp *app)
  501. {
  502.     if (app->progname)
  503.     {
  504.         struct DiskObject *dobj;
  505.  
  506.         if (dobj = GetDiskObject(app->progname))
  507.         {
  508.             char **tt = dobj->do_ToolTypes;
  509.             char *p;
  510.             
  511.             if (p = FindToolType(tt, "WINLEFT"))
  512.             {
  513.                 app->winx = atoi(p);
  514.             }
  515.     
  516.             if (p = FindToolType(tt, "WINTOP"))
  517.             {
  518.                 app->winy = atoi(p);
  519.             }
  520.     
  521.             if (p = FindToolType(tt, "WINWIDTH"))
  522.             {
  523.                 app->winwidth = atoi(p);
  524.             }
  525.     
  526.             if (p = FindToolType(tt, "WINHEIGHT"))
  527.             {
  528.                 app->winheight = atoi(p);
  529.             }
  530.         
  531.             FreeDiskObject(dobj);
  532.         }
  533.  
  534.     }
  535. }
  536.  
  537.  
  538. void SetTTEntry(struct List *ttlist, char *name, int value)
  539. {
  540.     BOOL found = FALSE;
  541.     char buffer[100];
  542.     struct Node *node, *nextnode;
  543.     int len = strlen(name), dlen;
  544.     char *newstring, *disabled;
  545.  
  546.     sprintf(buffer, "%s=%ld", name, value);
  547.     newstring = StrDup(buffer);
  548.     sprintf(buffer, "(%s", name);
  549.     disabled = StrDup(buffer);
  550.     
  551.     if (newstring && disabled)
  552.     {
  553.         dlen = strlen(disabled);
  554.         node = ttlist->lh_Head;
  555.         while (nextnode = node->ln_Succ)
  556.         {
  557.             if (strncmp(name, node->ln_Name, len) == 0)
  558.             {
  559.                 found = TRUE;
  560.             }
  561.             else if (strncmp(disabled, node->ln_Name, dlen) == 0)
  562.             {
  563.                 found = TRUE;            
  564.             }
  565.  
  566.             if (found)
  567.             {
  568.                 Free(node->ln_Name);
  569.                 node->ln_Name = newstring;
  570.                 newstring = NULL;
  571.                 break;
  572.             }
  573.             
  574.             node = nextnode;
  575.         }
  576.  
  577.         if (!found)
  578.         {
  579.             struct Node *newnode;
  580.             if (newnode = CreateNode(newstring))
  581.             {
  582.                 AddTail(ttlist, newnode);
  583.             }        
  584.         }
  585.     }
  586.  
  587.     Free(newstring);
  588.     Free(disabled);
  589.  
  590. }
  591.  
  592.  
  593. void WriteConfig(struct FlynnApp *app)
  594. {
  595.     if (app->progname && app->window)
  596.     {
  597.         struct DiskObject *dobj;
  598.         
  599.         dobj = GetDiskObject(app->progname);
  600.  
  601.         if (!dobj)
  602.         {
  603.             dobj = GetDefDiskObject(WBTOOL);
  604.         }
  605.         
  606.         if (dobj)
  607.         {
  608.             struct List *ttlist;
  609.             if (ttlist = CreateListFromArray(dobj->do_ToolTypes))
  610.             {
  611.                 char **newtt;
  612.  
  613.                 SetTTEntry(ttlist, "WINLEFT", app->window->window->LeftEdge);
  614.                 SetTTEntry(ttlist, "WINTOP", app->window->window->TopEdge);
  615.                 SetTTEntry(ttlist, "WINWIDTH", app->window->window->Width);
  616.                 SetTTEntry(ttlist, "WINHEIGHT", app->window->window->Height);
  617.                 
  618.                 if (newtt = CreateStringArrayFromList(ttlist))
  619.                 {
  620.                     dobj->do_ToolTypes = newtt;
  621.                     PutDiskObject(app->progname, dobj);
  622.                     FreeStringArray(newtt);
  623.                 }
  624.  
  625.                 DeleteList(ttlist);
  626.             }    
  627.             FreeDiskObject(dobj);
  628.         }
  629.     }
  630. }
  631.